﻿using Microsoft.Kinect;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace BodyTrain
{
   public static class BodyExtension
   {
       #region 定义常量属性
       //关节点
       public static readonly Brush trackedJointBrush = new SolidColorBrush(Color.FromArgb(255, 68, 192, 68));

       public static readonly Brush inferredJointBrush = Brushes.Yellow;

       public static readonly double JointThickness = 8;

       //手部状态
       public static readonly Brush handClosedBrush = new SolidColorBrush(Color.FromArgb(128, 255, 0, 0));

       public static readonly Brush handOpenBrush = new SolidColorBrush(Color.FromArgb(128, 0, 255, 0));

       public static readonly Brush handLassoBrush = new SolidColorBrush(Color.FromArgb(128, 0, 0, 255));

       public static readonly double HandSize = 50;
       #endregion

       #region 彩色图像映射函数
       public static Point ScaleTo(this Joint joint, CoordinateMapper coordinateMapper)
       {
           // 2D 空间点
           Point point = new Point();
           // 3D 空间点
           CameraSpacePoint jointPosition = joint.Position;

           ColorSpacePoint colorPoint = coordinateMapper.MapCameraPointToColorSpace(jointPosition);

           point.X = float.IsInfinity(colorPoint.X) ? 0 : colorPoint.X;
           point.Y = float.IsInfinity(colorPoint.Y) ? 0 : colorPoint.Y; 

           return point;
       }
       #endregion


       public static void DrawSkeleton(this Canvas canvas, Body body, CoordinateMapper coordinateMapper)
        {
            if (body == null) return;

            foreach (Joint joint in body.Joints.Values)
            {
                canvas.DrawPoint(joint, coordinateMapper);
            }

           //躯干
            canvas.DrawLine(body.Joints[JointType.Head], body.Joints[JointType.Neck], coordinateMapper);
            canvas.DrawLine(body.Joints[JointType.Neck], body.Joints[JointType.SpineShoulder], coordinateMapper);
            canvas.DrawLine(body.Joints[JointType.SpineShoulder], body.Joints[JointType.SpineMid], coordinateMapper);
            canvas.DrawLine(body.Joints[JointType.SpineMid], body.Joints[JointType.SpineBase], coordinateMapper);
            canvas.DrawLine(body.Joints[JointType.SpineShoulder], body.Joints[JointType.ShoulderRight], coordinateMapper);
            canvas.DrawLine(body.Joints[JointType.SpineShoulder], body.Joints[JointType.ShoulderLeft], coordinateMapper);
            canvas.DrawLine(body.Joints[JointType.SpineBase], body.Joints[JointType.HipLeft], coordinateMapper);
            canvas.DrawLine(body.Joints[JointType.SpineBase], body.Joints[JointType.HipRight], coordinateMapper);

           //右胳膊
            canvas.DrawLine(body.Joints[JointType.ShoulderRight], body.Joints[JointType.ElbowRight], coordinateMapper);
            canvas.DrawLine(body.Joints[JointType.ElbowRight], body.Joints[JointType.WristRight], coordinateMapper);
            canvas.DrawLine(body.Joints[JointType.WristRight], body.Joints[JointType.HandRight], coordinateMapper);
            canvas.DrawLine(body.Joints[JointType.HandRight], body.Joints[JointType.HandTipRight], coordinateMapper);
            canvas.DrawLine(body.Joints[JointType.WristRight], body.Joints[JointType.ThumbRight], coordinateMapper);

           //左胳膊
            canvas.DrawLine(body.Joints[JointType.ShoulderLeft], body.Joints[JointType.ElbowLeft], coordinateMapper);       
            canvas.DrawLine(body.Joints[JointType.ElbowLeft], body.Joints[JointType.WristLeft], coordinateMapper);          
            canvas.DrawLine(body.Joints[JointType.WristLeft], body.Joints[JointType.HandLeft], coordinateMapper);
            canvas.DrawLine(body.Joints[JointType.HandLeft], body.Joints[JointType.HandTipLeft], coordinateMapper);
            canvas.DrawLine(body.Joints[JointType.WristLeft], body.Joints[JointType.ThumbLeft], coordinateMapper);

           //右腿
            canvas.DrawLine(body.Joints[JointType.HipRight], body.Joints[JointType.KneeRight], coordinateMapper);
            canvas.DrawLine(body.Joints[JointType.KneeRight], body.Joints[JointType.AnkleRight], coordinateMapper);
            canvas.DrawLine(body.Joints[JointType.AnkleRight], body.Joints[JointType.FootRight], coordinateMapper);

           //左腿
            canvas.DrawLine(body.Joints[JointType.HipLeft], body.Joints[JointType.KneeLeft], coordinateMapper);
            canvas.DrawLine(body.Joints[JointType.KneeLeft], body.Joints[JointType.AnkleLeft], coordinateMapper);          
            canvas.DrawLine(body.Joints[JointType.AnkleLeft], body.Joints[JointType.FootLeft], coordinateMapper);    
       
           //画出手
            canvas.DrawHand(body.HandLeftState, body.Joints[JointType.HandLeft], coordinateMapper);
            canvas.DrawHand(body.HandRightState, body.Joints[JointType.HandRight], coordinateMapper);
        }

       public static void DrawPoint(this Canvas canvas, Joint joint, CoordinateMapper coordinateMapper)
        {      
            Point point = joint.ScaleTo(coordinateMapper);

            Brush drawBrush = null;

            TrackingState trackingState = joint.TrackingState;

            if (trackingState == TrackingState.Tracked)
                {
                    drawBrush = trackedJointBrush;
                }
                else if (trackingState == TrackingState.Inferred)
                {
                    drawBrush = inferredJointBrush;
                }

            if (drawBrush != null)
            {
                canvas.DrawEllipse(drawBrush, point, JointThickness, JointThickness);
            }
        }

       public static void DrawLine(this Canvas canvas, Joint first, Joint second, CoordinateMapper coordinateMapper)
        {
            if (first.TrackingState == TrackingState.NotTracked || second.TrackingState == TrackingState.NotTracked) return;

            if ((first.TrackingState == TrackingState.Tracked) && (second.TrackingState == TrackingState.Tracked))
            {
                Point point1 = first.ScaleTo(coordinateMapper);
                Point point2 = second.ScaleTo(coordinateMapper);

                Line line = new Line
                {
                    X1 = point1.X,
                    Y1 = point1.Y,
                    X2 = point2.X,
                    Y2 = point2.Y,
                    StrokeThickness = 3,
                    Stroke = new SolidColorBrush(Colors.Red)
                };
                canvas.Children.Add(line);
            }   
        }

       public static void DrawHand(this Canvas canvas, HandState handState, Joint joint, CoordinateMapper coordinateMapper)
       {
           Point handPosition = joint.ScaleTo(coordinateMapper);
           switch (handState)
           {
               case HandState.Closed:
                   canvas.DrawEllipse(handClosedBrush, handPosition, HandSize, HandSize);
                   break;

               case HandState.Open:
                   canvas.DrawEllipse(handOpenBrush, handPosition, HandSize, HandSize);
                   break;

               case HandState.Lasso:
                   canvas.DrawEllipse(handLassoBrush, handPosition, HandSize, HandSize);
                   break;
           }
       }
       public static void DrawEllipse(this Canvas canvas, Brush bush, Point center, double radiusX, double radiusY)
       {
           Ellipse ellipse = new Ellipse
           {
               Fill = bush,
               Width = radiusX,
               Height = radiusY
           };

           Canvas.SetLeft(ellipse, center.X - ellipse.Width / 2);
           Canvas.SetTop(ellipse, center.Y - ellipse.Height / 2);

           canvas.Children.Add(ellipse);
       }

       //计算两点间的垂直距离
       //右手举过头顶，锁定单人模式
       public static  double VerticalDistance(this Body body, JointType jointOne, JointType jointTwo)
       {
          return (body.Joints[jointOne].Position.Y - body.Joints[jointTwo].Position.Y);
       }

    }
}
